package com.ease.common.util;

import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Set;

/**
 * 
 * @author nathanleewei
 * 
 */
public abstract class ChineseSpellingUtil extends Detect {

	private static LinkedHashMap<String, Integer> spellMap = new LinkedHashMap<String, Integer>(400);

	static {
		initialize();
		// System.out.println("Chinese transfer Spell Done.");
	}

	private ChineseSpellingUtil() {
	}

	private static void p(String spell, int ascii) {
		spellMap.put(spell, new Integer(ascii));
	}

	private static void initialize() {
		p("a", -20319);
		p("ai", -20317);
		p("an", -20304);
		p("ang", -20295);
		p("ao", -20292);
		p("ba", -20283);
		p("bai", -20265);
		p("ban", -20257);
		p("bang", -20242);
		p("bao", -20230);
		p("bei", -20051);
		p("ben", -20036);
		p("beng", -20032);
		p("bi", -20026);
		p("bian", -20002);
		p("biao", -19990);
		p("bie", -19986);
		p("bin", -19982);
		p("bing", -19976);
		p("bo", -19805);
		p("bu", -19784);
		p("ca", -19775);
		p("cai", -19774);
		p("can", -19763);
		p("cang", -19756);
		p("cao", -19751);
		p("ce", -19746);
		p("ceng", -19741);
		p("cha", -19739);
		p("chai", -19728);
		p("chan", -19725);
		p("chang", -19715);
		p("chao", -19540);
		p("che", -19531);
		p("chen", -19525);
		p("cheng", -19515);
		p("chi", -19500);
		p("chong", -19484);
		p("chou", -19479);
		p("chu", -19467);
		p("chuai", -19289);
		p("chuan", -19288);
		p("chuang", -19281);
		p("chui", -19275);
		p("chun", -19270);
		p("chuo", -19263);
		p("ci", -19261);
		p("cong", -19249);
		p("cou", -19243);
		p("cu", -19242);
		p("cuan", -19238);
		p("cui", -19235);
		p("cun", -19227);
		p("cuo", -19224);
		p("da", -19218);
		p("dai", -19212);
		p("dan", -19038);
		p("dang", -19023);
		p("dao", -19018);
		p("de", -19006);
		p("deng", -19003);
		p("di", -18996);
		p("dian", -18977);
		p("diao", -18961);
		p("die", -18952);
		p("ding", -18783);
		p("diu", -18774);
		p("dong", -18773);
		p("dou", -18763);
		p("du", -18756);
		p("duan", -18741);
		p("dui", -18735);
		p("dun", -18731);
		p("duo", -18722);
		p("e", -18710);
		p("en", -18697);
		p("er", -18696);
		p("fa", -18526);
		p("fan", -18518);
		p("fang", -18501);
		p("fei", -18490);
		p("fen", -18478);
		p("feng", -18463);
		p("fo", -18448);
		p("fou", -18447);
		p("fu", -18446);
		p("ga", -18239);
		p("gai", -18237);
		p("gan", -18231);
		p("gang", -18220);
		p("gao", -18211);
		p("ge", -18201);
		p("gei", -18184);
		p("gen", -18183);
		p("geng", -18181);
		p("gong", -18012);
		p("gou", -17997);
		p("gu", -17988);
		p("gua", -17970);
		p("guai", -17964);
		p("guan", -17961);
		p("guang", -17950);
		p("gui", -17947);
		p("gun", -17931);
		p("guo", -17928);
		p("ha", -17922);
		p("hai", -17759);
		p("han", -17752);
		p("hang", -17733);
		p("hao", -17730);
		p("he", -17721);
		p("hei", -17703);
		p("hen", -17701);
		p("heng", -17697);
		p("hong", -17692);
		p("hou", -17683);
		p("hu", -17676);
		p("hua", -17496);
		p("huai", -17487);
		p("huan", -17482);
		p("huang", -17468);
		p("hui", -17454);
		p("hun", -17433);
		p("huo", -17427);
		p("ji", -17417);
		p("jia", -17202);
		p("jian", -17185);
		p("jiang", -16983);
		p("jiao", -16970);
		p("jie", -16942);
		p("jin", -16915);
		p("jing", -16733);
		p("jiong", -16708);
		p("jiu", -16706);
		p("ju", -16689);
		p("juan", -16664);
		p("jue", -16657);
		p("jun", -16647);
		p("ka", -16474);
		p("kai", -16470);
		p("kan", -16465);
		p("kang", -16459);
		p("kao", -16452);
		p("ke", -16448);
		p("ken", -16433);
		p("keng", -16429);
		p("kong", -16427);
		p("kou", -16423);
		p("ku", -16419);
		p("kua", -16412);
		p("kuai", -16407);
		p("kuan", -16403);
		p("kuang", -16401);
		p("kui", -16393);
		p("kun", -16220);
		p("kuo", -16216);
		p("la", -16212);
		p("lai", -16205);
		p("lan", -16202);
		p("lang", -16187);
		p("lao", -16180);
		p("le", -16171);
		p("lei", -16169);
		p("leng", -16158);
		p("li", -16155);
		p("lia", -15959);
		p("lian", -15958);
		p("liang", -15944);
		p("liao", -15933);
		p("lie", -15920);
		p("lin", -15915);
		p("ling", -15903);
		p("liu", -15889);
		p("long", -15878);
		p("lou", -15707);
		p("lu", -15701);
		p("lv", -15681);
		p("luan", -15667);
		p("lue", -15661);
		p("lun", -15659);
		p("luo", -15652);
		p("ma", -15640);
		p("mai", -15631);
		p("man", -15625);
		p("mang", -15454);
		p("mao", -15448);
		p("me", -15436);
		p("mei", -15435);
		p("men", -15419);
		p("meng", -15416);
		p("mi", -15408);
		p("mian", -15394);
		p("miao", -15385);
		p("mie", -15377);
		p("min", -15375);
		p("ming", -15369);
		p("miu", -15363);
		p("mo", -15362);
		p("mou", -15183);
		p("mu", -15180);
		p("na", -15165);
		p("nai", -15158);
		p("nan", -15153);
		p("nang", -15150);
		p("nao", -15149);
		p("ne", -15144);
		p("nei", -15143);
		p("nen", -15141);
		p("neng", -15140);
		p("ni", -15139);
		p("nian", -15128);
		p("niang", -15121);
		p("niao", -15119);
		p("nie", -15117);
		p("nin", -15110);
		p("ning", -15109);
		p("niu", -14941);
		p("nong", -14937);
		p("nu", -14933);
		p("nv", -14930);
		p("nuan", -14929);
		p("nue", -14928);
		p("nuo", -14926);
		p("o", -14922);
		p("ou", -14921);
		p("pa", -14914);
		p("pai", -14908);
		p("pan", -14902);
		p("pang", -14894);
		p("pao", -14889);
		p("pei", -14882);
		p("pen", -14873);
		p("peng", -14871);
		p("pi", -14857);
		p("pian", -14678);
		p("piao", -14674);
		p("pie", -14670);
		p("pin", -14668);
		p("ping", -14663);
		p("po", -14654);
		p("pu", -14645);
		p("qi", -14630);
		p("qia", -14594);
		p("qian", -14429);
		p("qiang", -14407);
		p("qiao", -14399);
		p("qie", -14384);
		p("qin", -14379);
		p("qing", -14368);
		p("qiong", -14355);
		p("qiu", -14353);
		p("qu", -14345);
		p("quan", -14170);
		p("que", -14159);
		p("qun", -14151);
		p("ran", -14149);
		p("rang", -14145);
		p("rao", -14140);
		p("re", -14137);
		p("ren", -14135);
		p("reng", -14125);
		p("ri", -14123);
		p("rong", -14122);
		p("rou", -14112);
		p("ru", -14109);
		p("ruan", -14099);
		p("rui", -14097);
		p("run", -14094);
		p("ruo", -14092);
		p("sa", -14090);
		p("sai", -14087);
		p("san", -14083);
		p("sang", -13917);
		p("sao", -13914);
		p("se", -13910);
		p("sen", -13907);
		p("seng", -13906);
		p("sha", -13905);
		p("shai", -13896);
		p("shan", -13894);
		p("shang", -13878);
		p("shao", -13870);
		p("she", -13859);
		p("shen", -13847);
		p("sheng", -13831);
		p("shi", -13658);
		p("shou", -13611);
		p("shu", -13601);
		p("shua", -13406);
		p("shuai", -13404);
		p("shuan", -13400);
		p("shuang", -13398);
		p("shui", -13395);
		p("shun", -13391);
		p("shuo", -13387);
		p("si", -13383);
		p("song", -13367);
		p("sou", -13359);
		p("su", -13356);
		p("suan", -13343);
		p("sui", -13340);
		p("sun", -13329);
		p("suo", -13326);
		p("ta", -13318);
		p("tai", -13147);
		p("tan", -13138);
		p("tang", -13120);
		p("tao", -13107);
		p("te", -13096);
		p("teng", -13095);
		p("ti", -13091);
		p("tian", -13076);
		p("tiao", -13068);
		p("tie", -13063);
		p("ting", -13060);
		p("tong", -12888);
		p("tou", -12875);
		p("tu", -12871);
		p("tuan", -12860);
		p("tui", -12858);
		p("tun", -12852);
		p("tuo", -12849);
		p("wa", -12838);
		p("wai", -12831);
		p("wan", -12829);
		p("wang", -12812);
		p("wei", -12802);
		p("wen", -12607);
		p("weng", -12597);
		p("wo", -12594);
		p("wu", -12585);
		p("xi", -12556);
		p("xia", -12359);
		p("xian", -12346);
		p("xiang", -12320);
		p("xiao", -12300);
		p("xie", -12120);
		p("xin", -12099);
		p("xing", -12089);
		p("xiong", -12074);
		p("xiu", -12067);
		p("xu", -12058);
		p("xuan", -12039);
		p("xue", -11867);
		p("xun", -11861);
		p("ya", -11847);
		p("yan", -11831);
		p("yang", -11798);
		p("yao", -11781);
		p("ye", -11604);
		p("yi", -11589);
		p("yin", -11536);
		p("ying", -11358);
		p("yo", -11340);
		p("yong", -11339);
		p("you", -11324);
		p("yu", -11303);
		p("yuan", -11097);
		p("yue", -11077);
		p("yun", -11067);
		p("za", -11055);
		p("zai", -11052);
		p("zan", -11045);
		p("zang", -11041);
		p("zao", -11038);
		p("ze", -11024);
		p("zei", -11020);
		p("zen", -11019);
		p("zeng", -11018);
		p("zha", -11014);
		p("zhai", -10838);
		p("zhan", -10832);
		p("zhang", -10815);
		p("zhao", -10800);
		p("zhe", -10790);
		p("zhen", -10780);
		p("zheng", -10764);
		p("zhi", -10587);
		p("zhong", -10544);
		p("zhou", -10533);
		p("zhu", -10519);
		p("zhua", -10331);
		p("zhuai", -10329);
		p("zhuan", -10328);
		p("zhuang", -10322);
		p("zhui", -10315);
		p("zhun", -10309);
		p("zhuo", -10307);
		p("zi", -10296);
		p("zong", -10281);
		p("zou", -10274);
		p("zu", -10270);
		p("zuan", -10262);
		p("zui", -10260);
		p("zun", -10256);
		p("zuo", -10254);
	}

	public static Integer getCnAscii(char cn) {
		try {
			byte[] bytes = (String.valueOf(cn)).getBytes("GBK");
			if (bytes == null || bytes.length > 2 || bytes.length <= 0) { //
				return new Integer(0);
			}
			if (bytes.length == 1) { // 英文字符
				return new Integer(bytes[0]);
			}
			if (bytes.length == 2) { // 中文字符
				int hightByte = 256 + bytes[0];
				int lowByte = 256 + bytes[1];

				int ascii = (256 * hightByte + lowByte) - 256 * 256;

				return new Integer(ascii);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}

		return new Integer(0); // 错误
	}

	public static String getSpellByAscii(int ascii) {
		if (ascii > 0 && ascii < 160) { // 单字符
			return String.valueOf((char) ascii);
		}

		if (ascii < -20319 || ascii > -10247) { // 不知道的字符
			return null;
		}

		Set<String> keySet = spellMap.keySet();
		Iterator<String> it = keySet.iterator();

		String spell0 = null;
		String spell = null;

		int asciiRang0 = -20319;
		int asciiRang;
		while (it.hasNext()) {

			spell = (String) it.next();
			Object valObj = spellMap.get(spell);
			if (valObj instanceof Integer) {
				asciiRang = ((Integer) valObj).intValue();

				if (ascii >= asciiRang0 && ascii < asciiRang) { // 区间找到
					return (spell0 == null) ? spell : spell0;
				} else {
					spell0 = spell;
					asciiRang0 = asciiRang;
				}
			}
		}

		return null;

	}

	public static String getFullSpell(String cnStr) {
		if (!notEmpty(cnStr)) {
			return cnStr;
		}

		char[] chars = cnStr.toCharArray();
		StringBuffer retuBuf = new StringBuffer();
		for (int i = 0, Len = chars.length; i < Len; i++) {
			int ascii = getCnAscii(chars[i]).intValue();
			if (ascii == 0) { // 取ascii时出错
				retuBuf.append(chars[i]);
			} else {
				String spell = getSpellByAscii(ascii);
				if (spell == null) {
					retuBuf.append(chars[i]);
				} else {
					retuBuf.append(spell);
				} // end of if spell == null
			} // end of if ascii <= -20400
		} // end of for

		return retuBuf.toString();
	}

	public static String getFirstSpell(String cnStr) {
		if (!notEmpty(cnStr)) {
			return cnStr;
		}

		char[] chars = cnStr.toCharArray();
		StringBuffer retuBuf = new StringBuffer();
		for (int i = 0, Len = chars.length; i < Len; i++) {
			int ascii = getCnAscii(chars[i]).intValue();
			if (ascii == 0) { // 取ascii时出错
				retuBuf.append(chars[i]);
			} else {
				String spell = getSpellByAscii(ascii);
				if (spell == null) {
					retuBuf.append(chars[i]);
				} else {
					if (spell.length() > 0) {
						if (ascii > 0 && ascii < 160) { // 单字符
							retuBuf.append(spell.charAt(0));
						} else {
							retuBuf.append(Character.toUpperCase(spell.charAt(0)));
						}
					}
				} // end of if spell == null
			} // end of if ascii <= -20400
		} // end of for

		return retuBuf.toString();
	}

	// move to ChineseToSpellUtilTest
	// public static void main(String[] args) {
	// String str = null;
	// str = "李忠南-aa";
	// System.out.println("Spell=" + getFullSpell(str));
	// System.out.println("Spell=" + getFirstSpell(str));
	// }
}